using System;
using System.Globalization;
using System.Reflection;
using System.Windows.Data;

namespace RanbuUI.Converters
{
    public class EnumFlagToBooleanConverter : IValueConverter
    {
        private readonly object host;
        private readonly string propertyName;

        private PropertyInfo propertyInfo;
        private PropertyInfo PropertyInfo
        {
            get
            {
                if (this.propertyInfo == null && this.host != null)
                {
                    this.propertyInfo = this.host.GetType().GetProperty(this.propertyName);
                }

                return this.propertyInfo;
            }
        }

        public EnumFlagToBooleanConverter(object host, string propertyName)
        {
            this.host = host;
            this.propertyName = propertyName;
        }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var numericParam = System.Convert.ToUInt64(parameter);
            var numericValue = System.Convert.ToUInt64(value);
            if (numericParam == 0)
            {
                return numericValue == 0;
            }
            else
            {
                return (numericValue & numericParam) == numericParam;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var result = System.Convert.ToUInt64(this.PropertyInfo.GetValue(this.host, null));
            var checking = (bool)value;
            var checkingValue = System.Convert.ToUInt64(parameter);
            if (checking)
            {
                if (checkingValue == 0) { result = 0; }
                else { result |= checkingValue; }
            }
            else { result ^= checkingValue; }

            return Enum.ToObject(targetType, result);
        }
    }
}